ODS 1

1.1.1

library(readxl)
url <- "https://github.com/ChiaraZamoraM/ODS/raw/main/1.1.1.xlsx"
destfile <- "X1_1_1.xlsx"
curl::curl_download(url, destfile)
X1_1_1 <- read_excel(destfile, skip = 28)
New names:
* `` -> ...1
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5
* ...
colnames(X1_1_1) = paste0("ODS1_1_1_",colnames(X1_1_1))

X1_1_1 = X1_1_1[,c(1,10:26)]

names(X1_1_1)
 [1] "ODS1_1_1_...1"  "ODS1_1_1_...10" "ODS1_1_1_2013"  "ODS1_1_1_...12" "ODS1_1_1_2014" 
 [6] "ODS1_1_1_...14" "ODS1_1_1_2015"  "ODS1_1_1_...16" "ODS1_1_1_2016"  "ODS1_1_1_...18"
[11] "ODS1_1_1_2017"  "ODS1_1_1_...20" "ODS1_1_1_2018"  "ODS1_1_1_...22" "ODS1_1_1_2019" 
[16] "ODS1_1_1_...24" "ODS1_1_1_2020"  "ODS1_1_1_...26"
X1_1_1[,c(2:18)]=lapply(X1_1_1[,c(2:18)], as.numeric)
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_1_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
X1_1_1$ODS1_1_1_2013= (X1_1_1$ODS1_1_1_2013+ X1_1_1$ODS1_1_1_...12)/2
X1_1_1$ODS1_1_1_2014= (X1_1_1$ODS1_1_1_2014+ X1_1_1$ODS1_1_1_...14)/2
X1_1_1$ODS1_1_1_2015= (X1_1_1$ODS1_1_1_2015+ X1_1_1$ODS1_1_1_...16)/2
X1_1_1$ODS1_1_1_2016= (X1_1_1$ODS1_1_1_2016+ X1_1_1$ODS1_1_1_...18)/2
X1_1_1$ODS1_1_1_2017= (X1_1_1$ODS1_1_1_2017+ X1_1_1$ODS1_1_1_...20)/2
X1_1_1$ODS1_1_1_2018= (X1_1_1$ODS1_1_1_2018+ X1_1_1$ODS1_1_1_...22)/2
X1_1_1$ODS1_1_1_2019= (X1_1_1$ODS1_1_1_2019+ X1_1_1$ODS1_1_1_...24)/2
X1_1_1$ODS1_1_1_2020= (X1_1_1$ODS1_1_1_2020+ X1_1_1$ODS1_1_1_...26)/2
names(X1_1_1)[1]= "DEPARTAMENTO"
X1_1_1 <- data.frame(X1_1_1[,seq(1,18,2)])

X1_1_1$DEPARTAMENTO= gsub("Lima Metropolitana","LIMA",X1_1_1$DEPARTAMENTO)
X1_1_1$DEPARTAMENTO= gsub("Lima","LIMA PROVINCIAS",X1_1_1$DEPARTAMENTO)

1.2.1

url <- "https://github.com/ChiaraZamoraM/ODS/raw/main/1.2.1.xlsx"
destfile <- "X1_2_1.xlsx"
curl::curl_download(url, destfile)
X1_2_1 <- read_excel(destfile, skip = 28)
New names:
* `` -> ...1
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...6
* ...
colnames(X1_2_1) = paste0("ODS1_2_1_",colnames(X1_2_1))

X1_2_1 = X1_2_1[,c(1,16:32)]

names(X1_2_1)
 [1] "ODS1_2_1_...1"  "ODS1_2_1_...16" "ODS1_2_1_2013"  "ODS1_2_1_...18" "ODS1_2_1_2014" 
 [6] "ODS1_2_1_...20" "ODS1_2_1_2015"  "ODS1_2_1_...22" "ODS1_2_1_2016"  "ODS1_2_1_...24"
[11] "ODS1_2_1_2017"  "ODS1_2_1_...26" "ODS1_2_1_2018"  "ODS1_2_1_...28" "ODS1_2_1_2019" 
[16] "ODS1_2_1_...30" "ODS1_2_1_2020"  "ODS1_2_1_...32"
X1_2_1[,c(2:18)]=lapply(X1_2_1[,c(2:18)], as.numeric)
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(X1_2_1[, c(2:18)], as.numeric) :
  NAs introduced by coercion
X1_2_1$ODS1_2_1_2013= (X1_2_1$ODS1_2_1_2013+ X1_2_1$ODS1_2_1_...18)/2
X1_2_1$ODS1_2_1_2014= (X1_2_1$ODS1_2_1_2014+ X1_2_1$ODS1_2_1_...20)/2
X1_2_1$ODS1_2_1_2015= (X1_2_1$ODS1_2_1_2015+ X1_2_1$ODS1_2_1_...22)/2
X1_2_1$ODS1_2_1_2016= (X1_2_1$ODS1_2_1_2016+ X1_2_1$ODS1_2_1_...24)/2
X1_2_1$ODS1_2_1_2017= (X1_2_1$ODS1_2_1_2017+ X1_2_1$ODS1_2_1_...26)/2
X1_2_1$ODS1_2_1_2018= (X1_2_1$ODS1_2_1_2018+ X1_2_1$ODS1_2_1_...28)/2
X1_2_1$ODS1_2_1_2019= (X1_2_1$ODS1_2_1_2019+ X1_2_1$ODS1_2_1_...30)/2
X1_2_1$ODS1_2_1_2020= (X1_2_1$ODS1_2_1_2020+ X1_2_1$ODS1_2_1_...32)/2
names(X1_2_1)[1]= "DEPARTAMENTO"
X1_2_1 <- data.frame(X1_2_1[,seq(1,18,2)])

X1_2_1$DEPARTAMENTO= gsub("Lima Metropolitana","LIMA",X1_2_1$DEPARTAMENTO)
X1_2_1$DEPARTAMENTO= gsub("Lima","LIMA PROVINCIAS",X1_2_1$DEPARTAMENTO)

1.3.1

url <- "https://github.com/ChiaraZamoraM/ODS/raw/main/1.3.1.xlsx"
destfile <- "X1_3_1.xlsx"
curl::curl_download(url, destfile)
X1_3_1 <- read_excel(destfile, skip = 7)
New names:
* `` -> ...1
colnames(X1_3_1) = paste0("ODS1_3_1_",colnames(X1_3_1))
X1_3_1[,c(2:14)]=lapply(X1_3_1[,c(2:14)], as.numeric)

names(X1_3_1)[1]= "DEPARTAMENTO"
X1_3_1$DEPARTAMENTO= gsub("Prov. Const. del Callao","Callao",X1_3_1$DEPARTAMENTO)
X1_3_1$DEPARTAMENTO= gsub("Provincia de Lima","LIMA",X1_3_1$DEPARTAMENTO)
X1_3_1$DEPARTAMENTO= gsub("Región Lima","LIMA PROVINCIAS",X1_3_1$DEPARTAMENTO)

1.4.1

ODS_1 = Reduce(function(x, y) merge(x, y, by= "DEPARTAMENTO"), list(X1_1_1, X1_2_1, X1_3_1, X1_4_1))
X1_4_1[,c(2:8)]=lapply(X1_4_1[,c(2:8)], as.numeric)

names(X1_4_1)[1]= "DEPARTAMENTO"
X1_4_1$DEPARTAMENTO= gsub("Prov. Const. del Callao","Callao",X1_4_1$DEPARTAMENTO)
X1_4_1$DEPARTAMENTO= gsub("Provincia de Lima","LIMA",X1_4_1$DEPARTAMENTO)
X1_4_1$DEPARTAMENTO= gsub("Región Lima","LIMA PROVINCIAS",X1_4_1$DEPARTAMENTO)

Merge

ODS_1 = Reduce(function(x, y) merge(x, y, by= "DEPARTAMENTO"), list(X1_1_1, X1_2_1, X1_3_1, X1_4_1))

ODS 2

url <- "https://www.inei.gob.pe/media/MenuRecursivo/publicaciones_digitales/Est/Lib1795/cuadros/Cap010.xls"
destfile <- "Cap010.xls"
curl::curl_download(url, destfile)
Cap010 <- read_excel(destfile,sheet = "10.18",skip = 6)
New names:
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5
* `` -> ...6
* ...
names(Cap010)[c(1,4)]= c("DEPARTAMENTO","2020")
Cap010 =Cap010[,c(1,4)]

Cap010$DEPARTAMENTO =gsub(' [0-9].', '', Cap010$DEPARTAMENTO)
url <- "https://www.inei.gob.pe/media/MenuRecursivo/publicaciones_digitales/Est/Lib1795/cuadros/Cap010.xls"
destfile <- "Cap010.xls"
curl::curl_download(url, destfile)
Cap010_2 <- read_excel(destfile,sheet = "10.18",skip = 6)
New names:
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5
* `` -> ...6
* ...
names(Cap010_2)[c(1,7)]= c("DEPARTAMENTO","2020")
Cap010_2 =Cap010_2[,c(1,7)]

Cap010_2$DEPARTAMENTO =gsub(' [0-9].', '', Cap010_2$DEPARTAMENTO)

2.1.1

url <- "https://github.com/ChiaraZamoraM/ODS/raw/main/2.2.1.xlsx"
destfile <- "X2_2_1.xlsx"
curl::curl_download(url, destfile)
X2_2_1 <- read_excel(destfile, skip = 7)
New names:
* `` -> ...1
names(X2_2_1)[1]= "DEPARTAMENTO"

Cap010$DEPARTAMENTO= gsub("Prov. Const. del Callao","Callao",Cap010$DEPARTAMENTO)
Cap010$DEPARTAMENTO= gsub("Lima Metropolitana","LIMA",Cap010$DEPARTAMENTO)
Cap010$DEPARTAMENTO= gsub("Departamento de Lima","LIMA PROVINCIAS",Cap010$DEPARTAMENTO)

X2_2_1$DEPARTAMENTO= gsub("Prov. Const. del Callao","Callao",X2_2_1$DEPARTAMENTO)
X2_2_1$DEPARTAMENTO= gsub("Provincia de Lima","LIMA",X2_2_1$DEPARTAMENTO)
X2_2_1$DEPARTAMENTO= gsub("Región Lima","LIMA PROVINCIAS",X2_2_1$DEPARTAMENTO)

X2_2_1 = merge(X2_2_1, Cap010, by = "DEPARTAMENTO")

names(X2_2_1)[c(2:15)] = paste0("ODS2_2_1_",names(X2_2_1)[c(2:15)])

2.2.1

url <- "https://github.com/ChiaraZamoraM/ODS/raw/main/2.2.2.xlsx"
destfile <- "X2_2_2.xlsx"
curl::curl_download(url, destfile)
X2_2_2 <- read_excel(destfile, skip = 7)
New names:
* `` -> ...1
names(X2_2_2)[1]= "DEPARTAMENTO"
Cap010_2$DEPARTAMENTO= gsub("Prov. Const. del Callao","Callao",Cap010_2$DEPARTAMENTO)
Cap010_2$DEPARTAMENTO= gsub("Lima Metropolitana","LIMA",Cap010_2$DEPARTAMENTO)
Cap010_2$DEPARTAMENTO= gsub("Departamento de Lima","LIMA PROVINCIAS",Cap010_2$DEPARTAMENTO)

X2_2_2$DEPARTAMENTO= gsub("Prov. Const. del Callao","Callao",X2_2_2$DEPARTAMENTO)
X2_2_2$DEPARTAMENTO= gsub("Provincia de Lima","LIMA",X2_2_2$DEPARTAMENTO)
X2_2_2$DEPARTAMENTO= gsub("Región Lima","LIMA PROVINCIAS",X2_2_2$DEPARTAMENTO)
X2_2_2 = merge(X2_2_2, Cap010_2, by = "DEPARTAMENTO")

colnames(X2_2_2)[c(2:12)] = paste0("ODS2_2_2_",colnames(X2_2_2)[c(2:12)])

str(X2_2_2)
'data.frame':   34 obs. of  12 variables:
 $ DEPARTAMENTO : chr  "Amazonas" "Áncash" "Apurímac" "Arequipa" ...
 $ ODS2_2_2_2010: chr  "0.6" "0.3" "0.3" "0.5" ...
 $ ODS2_2_2_2011: chr  "0.8" "0.3" "0.5" "0.3" ...
 $ ODS2_2_2_2012: chr  "0.7" "0.4" "0.5" "0" ...
 $ ODS2_2_2_2013: chr  "0.1" "0.3" "0.4" "0.8" ...
 $ ODS2_2_2_2014: num  0.4 0.2 0.3 0.3 0.2 0.4 0 0.3 0.2 0.9 ...
 $ ODS2_2_2_2015: num  0.7 0.6 1.2 0 0.9 0.6 0.5 0.4 1.8 1.4 ...
 $ ODS2_2_2_2016: num  0.6 0.1 0.7 0 1.2 0.4 0.2 1.7 1.3 0.3 ...
 $ ODS2_2_2_2017: num  1.3 0.1 0.6 0.7 0.7 0.5 0.2 0.8 0.3 0.6 ...
 $ ODS2_2_2_2018: num  1.2 0.2 0.4 0.1 0.5 0.2 0 0.3 0.7 0.3 ...
 $ ODS2_2_2_2019: num  1.1 0.1 0.1 0.1 0.6 1 0.2 0.8 0.2 0.1 ...
 $ ODS2_2_2_2020: num  0.9385 0.0757 0.3944 0.1938 0.6927 ...

Merge

ODS_2 = Reduce(function(x, y) merge(x, y, by= "DEPARTAMENTO"), list(X2_2_1,X2_2_2))
ODS_2[,c(2:26)]=lapply(ODS_2[,c(2:26)], as.numeric)
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion
Warning in lapply(ODS_2[, c(2:26)], as.numeric) :
  NAs introduced by coercion

Merge

ODS = Reduce(function(x, y) merge(x, y, by= "DEPARTAMENTO"), list(ODS_1,ODS_2))

library(stringi)
ODS$DEPARTAMENTO= stri_trans_general(str = toupper(ODS$DEPARTAMENTO), id = "Latin-ASCII")
ODSTrans$Ano = year(ODSTrans$Ano)
Error in as.POSIXlt.character(x, tz = tz(x)) : 
  character string is not in a standard unambiguous format
mapa_prov <- st_read("PROVINCIAS.shp")
Reading layer `PROVINCIAS' from data source `C:\Users\soyma\Documents\GitHub\ODS\PROVINCIAS.shp' using driver `ESRI Shapefile'
Simple feature collection with 196 features and 6 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -81.32823 ymin: -18.35093 xmax: -68.65228 ymax: -0.03860597
Geodetic CRS:  WGS 84
summary(subset1_1_1$Valor)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.25    0.50    3.05    4.29    6.85   20.25 

subset1_2_1= subset(mapaODS, ODSNro=="1_2_1" & Ano> 2014)

base1_2_1= ggplot(data = subset1_2_1) + theme_light()
library(plotly)

mapaley2 = base1_2_1 +
  geom_sf(aes(fill= Valor)) + labs(fill = "Porcentaje (%)") +
  geom_sf(data = mapa_prov,
          fill = NA) +
  facet_wrap(~Ano)
      
mapa2 = mapaley2 + 
  scale_fill_gradient(low = "yellow",  high = "darkred")+ 
  labs(title = "Incidencia de la pobreza extrema", subtitle = "Indicador 1.1.1") 

mapa2

subset1_3_1= subset(mapaODS, ODSNro=="1_3_1" & Ano> 2014)

base1_3_1= ggplot(data = subset1_3_1) + theme_light()
library(plotly)

mapaley3 = base1_3_1 +
  geom_sf(aes(fill= Valor)) + labs(fill = "Porcentaje (%)") +
  geom_sf(data = mapa_prov,
          fill = NA) +
  facet_wrap(~Ano)
      
mapa3 = mapaley3 + 
  scale_fill_gradient(low = "lightpink",  high = "firebrick2")+ 
  labs(title = "Proporción de población de 14 a más años de edad \ncon seguro de pensión", subtitle = "Indicador 1.3.1") 

mapa3
subset1_4_1= subset(mapaODS, ODSNro=="1_4_1" & Ano> 2014)

base1_4_1= ggplot(data = subset1_4_1) + theme_light()
library(plotly)

mapaley4 = base1_4_1 +
  geom_sf(aes(fill= Valor)) + labs(fill = "Porcentaje (%)") +
  geom_sf(data = mapa_prov,
          fill = NA) +
  facet_wrap(~Ano)
      
mapa4 = mapaley4 + 
  scale_fill_gradient(low = "lightpink",  high = "firebrick2")+ 
  labs(title = "Proporción de la población que vive en hogares con \nacceso a servicios básicos de infraestructura", subtitle = "Indicador 1.4.1") 

mapa4
library(leaflet)
pal1 =colorNumeric(palette = "OrRd", domain = subset1_1_1$Valor])
Error: unexpected ']' in "pal1 =colorNumeric(palette = "OrRd", domain = subset1_1_1$Valor]"
names(subset1_1_1)
[1] "DEPARTAMEN" "IDDPTO"     "id"         "ODS_Ano"    "Valor"      "Ano"        "ODSNro"    
[8] "geometry"  
saveWidget(map1_interactive, "ODS1_1_1")
[WARNING] Could not deduce format from file extension 
  Defaulting to html
LS0tDQp0aXRsZTogIlByb2Nlc2FtaWVudG8gZGUgaW5kaWNhZG9yZXMgZGUgT0RTIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMgT0RTIDENCg0KIyMgMS4xLjENCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQp1cmwgPC0gImh0dHBzOi8vZ2l0aHViLmNvbS9DaGlhcmFaYW1vcmFNL09EUy9yYXcvbWFpbi8xLjEuMS54bHN4Ig0KZGVzdGZpbGUgPC0gIlgxXzFfMS54bHN4Ig0KY3VybDo6Y3VybF9kb3dubG9hZCh1cmwsIGRlc3RmaWxlKQ0KWDFfMV8xIDwtIHJlYWRfZXhjZWwoZGVzdGZpbGUsIHNraXAgPSAyOCkNCg0KY29sbmFtZXMoWDFfMV8xKSA9IHBhc3RlMCgiT0RTMV8xXzFfIixjb2xuYW1lcyhYMV8xXzEpKQ0KDQpYMV8xXzEgPSBYMV8xXzFbLGMoMSwxMDoyNildDQoNCm5hbWVzKFgxXzFfMSkNCmBgYA0KDQpgYGB7cn0NClgxXzFfMVssYygyOjE4KV09bGFwcGx5KFgxXzFfMVssYygyOjE4KV0sIGFzLm51bWVyaWMpDQpgYGANCg0KYGBge3J9DQpYMV8xXzEkT0RTMV8xXzFfMjAxMz0gKFgxXzFfMSRPRFMxXzFfMV8yMDEzKyBYMV8xXzEkT0RTMV8xXzFfLi4uMTIpLzINClgxXzFfMSRPRFMxXzFfMV8yMDE0PSAoWDFfMV8xJE9EUzFfMV8xXzIwMTQrIFgxXzFfMSRPRFMxXzFfMV8uLi4xNCkvMg0KWDFfMV8xJE9EUzFfMV8xXzIwMTU9IChYMV8xXzEkT0RTMV8xXzFfMjAxNSsgWDFfMV8xJE9EUzFfMV8xXy4uLjE2KS8yDQpYMV8xXzEkT0RTMV8xXzFfMjAxNj0gKFgxXzFfMSRPRFMxXzFfMV8yMDE2KyBYMV8xXzEkT0RTMV8xXzFfLi4uMTgpLzINClgxXzFfMSRPRFMxXzFfMV8yMDE3PSAoWDFfMV8xJE9EUzFfMV8xXzIwMTcrIFgxXzFfMSRPRFMxXzFfMV8uLi4yMCkvMg0KWDFfMV8xJE9EUzFfMV8xXzIwMTg9IChYMV8xXzEkT0RTMV8xXzFfMjAxOCsgWDFfMV8xJE9EUzFfMV8xXy4uLjIyKS8yDQpYMV8xXzEkT0RTMV8xXzFfMjAxOT0gKFgxXzFfMSRPRFMxXzFfMV8yMDE5KyBYMV8xXzEkT0RTMV8xXzFfLi4uMjQpLzINClgxXzFfMSRPRFMxXzFfMV8yMDIwPSAoWDFfMV8xJE9EUzFfMV8xXzIwMjArIFgxXzFfMSRPRFMxXzFfMV8uLi4yNikvMg0KbmFtZXMoWDFfMV8xKVsxXT0gIkRFUEFSVEFNRU5UTyINCmBgYA0KDQpgYGB7cn0NClgxXzFfMSA8LSBkYXRhLmZyYW1lKFgxXzFfMVssc2VxKDEsMTgsMildKQ0KDQpYMV8xXzEkREVQQVJUQU1FTlRPPSBnc3ViKCJMaW1hIE1ldHJvcG9saXRhbmEiLCJMSU1BIixYMV8xXzEkREVQQVJUQU1FTlRPKQ0KWDFfMV8xJERFUEFSVEFNRU5UTz0gZ3N1YigiTGltYSIsIkxJTUEgUFJPVklOQ0lBUyIsWDFfMV8xJERFUEFSVEFNRU5UTykNCmBgYA0KDQojIyAxLjIuMQ0KYGBge3J9DQp1cmwgPC0gImh0dHBzOi8vZ2l0aHViLmNvbS9DaGlhcmFaYW1vcmFNL09EUy9yYXcvbWFpbi8xLjIuMS54bHN4Ig0KZGVzdGZpbGUgPC0gIlgxXzJfMS54bHN4Ig0KY3VybDo6Y3VybF9kb3dubG9hZCh1cmwsIGRlc3RmaWxlKQ0KWDFfMl8xIDwtIHJlYWRfZXhjZWwoZGVzdGZpbGUsIHNraXAgPSAyOCkNCg0KY29sbmFtZXMoWDFfMl8xKSA9IHBhc3RlMCgiT0RTMV8yXzFfIixjb2xuYW1lcyhYMV8yXzEpKQ0KDQpYMV8yXzEgPSBYMV8yXzFbLGMoMSwxNjozMildDQoNCm5hbWVzKFgxXzJfMSkNCmBgYA0KYGBge3J9DQpYMV8yXzFbLGMoMjoxOCldPWxhcHBseShYMV8yXzFbLGMoMjoxOCldLCBhcy5udW1lcmljKQ0KYGBgDQoNCmBgYHtyfQ0KWDFfMl8xJE9EUzFfMl8xXzIwMTM9IChYMV8yXzEkT0RTMV8yXzFfMjAxMysgWDFfMl8xJE9EUzFfMl8xXy4uLjE4KS8yDQpYMV8yXzEkT0RTMV8yXzFfMjAxND0gKFgxXzJfMSRPRFMxXzJfMV8yMDE0KyBYMV8yXzEkT0RTMV8yXzFfLi4uMjApLzINClgxXzJfMSRPRFMxXzJfMV8yMDE1PSAoWDFfMl8xJE9EUzFfMl8xXzIwMTUrIFgxXzJfMSRPRFMxXzJfMV8uLi4yMikvMg0KWDFfMl8xJE9EUzFfMl8xXzIwMTY9IChYMV8yXzEkT0RTMV8yXzFfMjAxNisgWDFfMl8xJE9EUzFfMl8xXy4uLjI0KS8yDQpYMV8yXzEkT0RTMV8yXzFfMjAxNz0gKFgxXzJfMSRPRFMxXzJfMV8yMDE3KyBYMV8yXzEkT0RTMV8yXzFfLi4uMjYpLzINClgxXzJfMSRPRFMxXzJfMV8yMDE4PSAoWDFfMl8xJE9EUzFfMl8xXzIwMTgrIFgxXzJfMSRPRFMxXzJfMV8uLi4yOCkvMg0KWDFfMl8xJE9EUzFfMl8xXzIwMTk9IChYMV8yXzEkT0RTMV8yXzFfMjAxOSsgWDFfMl8xJE9EUzFfMl8xXy4uLjMwKS8yDQpYMV8yXzEkT0RTMV8yXzFfMjAyMD0gKFgxXzJfMSRPRFMxXzJfMV8yMDIwKyBYMV8yXzEkT0RTMV8yXzFfLi4uMzIpLzINCm5hbWVzKFgxXzJfMSlbMV09ICJERVBBUlRBTUVOVE8iDQpgYGANCg0KYGBge3J9DQpYMV8yXzEgPC0gZGF0YS5mcmFtZShYMV8yXzFbLHNlcSgxLDE4LDIpXSkNCg0KWDFfMl8xJERFUEFSVEFNRU5UTz0gZ3N1YigiTGltYSBNZXRyb3BvbGl0YW5hIiwiTElNQSIsWDFfMl8xJERFUEFSVEFNRU5UTykNClgxXzJfMSRERVBBUlRBTUVOVE89IGdzdWIoIkxpbWEiLCJMSU1BIFBST1ZJTkNJQVMiLFgxXzJfMSRERVBBUlRBTUVOVE8pDQpgYGANCg0KIyMgMS4zLjENCmBgYHtyfQ0KdXJsIDwtICJodHRwczovL2dpdGh1Yi5jb20vQ2hpYXJhWmFtb3JhTS9PRFMvcmF3L21haW4vMS4zLjEueGxzeCINCmRlc3RmaWxlIDwtICJYMV8zXzEueGxzeCINCmN1cmw6OmN1cmxfZG93bmxvYWQodXJsLCBkZXN0ZmlsZSkNClgxXzNfMSA8LSByZWFkX2V4Y2VsKGRlc3RmaWxlLCBza2lwID0gNykNCg0KY29sbmFtZXMoWDFfM18xKSA9IHBhc3RlMCgiT0RTMV8zXzFfIixjb2xuYW1lcyhYMV8zXzEpKQ0KYGBgDQoNCmBgYHtyfQ0KWDFfM18xWyxjKDI6MTQpXT1sYXBwbHkoWDFfM18xWyxjKDI6MTQpXSwgYXMubnVtZXJpYykNCg0KbmFtZXMoWDFfM18xKVsxXT0gIkRFUEFSVEFNRU5UTyINCmBgYA0KDQpgYGB7cn0NClgxXzNfMSRERVBBUlRBTUVOVE89IGdzdWIoIlByb3YuIENvbnN0LiBkZWwgQ2FsbGFvIiwiQ2FsbGFvIixYMV8zXzEkREVQQVJUQU1FTlRPKQ0KWDFfM18xJERFUEFSVEFNRU5UTz0gZ3N1YigiUHJvdmluY2lhIGRlIExpbWEiLCJMSU1BIixYMV8zXzEkREVQQVJUQU1FTlRPKQ0KWDFfM18xJERFUEFSVEFNRU5UTz0gZ3N1YigiUmVnacOzbiBMaW1hIiwiTElNQSBQUk9WSU5DSUFTIixYMV8zXzEkREVQQVJUQU1FTlRPKQ0KYGBgDQoNCiMjIDEuNC4xDQpgYGB7cn0NCnVybCA8LSAiaHR0cHM6Ly9naXRodWIuY29tL0NoaWFyYVphbW9yYU0vT0RTL3Jhdy9tYWluLzEuNC4xLnhsc3giDQpkZXN0ZmlsZSA8LSAiWDFfM18xLnhsc3giDQpjdXJsOjpjdXJsX2Rvd25sb2FkKHVybCwgZGVzdGZpbGUpDQpYMV80XzEgPC0gcmVhZF9leGNlbChkZXN0ZmlsZSwgc2tpcCA9IDcpDQoNCmNvbG5hbWVzKFgxXzRfMSkgPSBwYXN0ZTAoIk9EUzFfNF8xXyIsY29sbmFtZXMoWDFfNF8xKSkNCmBgYA0KDQpgYGB7cn0NClgxXzRfMVssYygyOjgpXT1sYXBwbHkoWDFfNF8xWyxjKDI6OCldLCBhcy5udW1lcmljKQ0KDQpuYW1lcyhYMV80XzEpWzFdPSAiREVQQVJUQU1FTlRPIg0KYGBgDQoNCmBgYHtyfQ0KWDFfNF8xJERFUEFSVEFNRU5UTz0gZ3N1YigiUHJvdi4gQ29uc3QuIGRlbCBDYWxsYW8iLCJDYWxsYW8iLFgxXzRfMSRERVBBUlRBTUVOVE8pDQpYMV80XzEkREVQQVJUQU1FTlRPPSBnc3ViKCJQcm92aW5jaWEgZGUgTGltYSIsIkxJTUEiLFgxXzRfMSRERVBBUlRBTUVOVE8pDQpYMV80XzEkREVQQVJUQU1FTlRPPSBnc3ViKCJSZWdpw7NuIExpbWEiLCJMSU1BIFBST1ZJTkNJQVMiLFgxXzRfMSRERVBBUlRBTUVOVE8pDQpgYGANCg0KIyMgTWVyZ2UNCmBgYHtyfQ0KT0RTXzEgPSBSZWR1Y2UoZnVuY3Rpb24oeCwgeSkgbWVyZ2UoeCwgeSwgYnk9ICJERVBBUlRBTUVOVE8iKSwgbGlzdChYMV8xXzEsIFgxXzJfMSwgWDFfM18xLCBYMV80XzEpKQ0KYGBgDQoNCiMgT0RTIDINCg0KYGBge3J9DQp1cmwgPC0gImh0dHBzOi8vd3d3LmluZWkuZ29iLnBlL21lZGlhL01lbnVSZWN1cnNpdm8vcHVibGljYWNpb25lc19kaWdpdGFsZXMvRXN0L0xpYjE3OTUvY3VhZHJvcy9DYXAwMTAueGxzIg0KZGVzdGZpbGUgPC0gIkNhcDAxMC54bHMiDQpjdXJsOjpjdXJsX2Rvd25sb2FkKHVybCwgZGVzdGZpbGUpDQpDYXAwMTAgPC0gcmVhZF9leGNlbChkZXN0ZmlsZSxzaGVldCA9ICIxMC4xOCIsc2tpcCA9IDYpDQoNCm5hbWVzKENhcDAxMClbYygxLDQpXT0gYygiREVQQVJUQU1FTlRPIiwiMjAyMCIpDQpDYXAwMTAgPUNhcDAxMFssYygxLDQpXQ0KDQpDYXAwMTAkREVQQVJUQU1FTlRPID1nc3ViKCcgWzAtOV0uJywgJycsIENhcDAxMCRERVBBUlRBTUVOVE8pDQpgYGANCg0KYGBge3J9DQp1cmwgPC0gImh0dHBzOi8vd3d3LmluZWkuZ29iLnBlL21lZGlhL01lbnVSZWN1cnNpdm8vcHVibGljYWNpb25lc19kaWdpdGFsZXMvRXN0L0xpYjE3OTUvY3VhZHJvcy9DYXAwMTAueGxzIg0KZGVzdGZpbGUgPC0gIkNhcDAxMC54bHMiDQpjdXJsOjpjdXJsX2Rvd25sb2FkKHVybCwgZGVzdGZpbGUpDQpDYXAwMTBfMiA8LSByZWFkX2V4Y2VsKGRlc3RmaWxlLHNoZWV0ID0gIjEwLjE4Iixza2lwID0gNikNCg0KbmFtZXMoQ2FwMDEwXzIpW2MoMSw3KV09IGMoIkRFUEFSVEFNRU5UTyIsIjIwMjAiKQ0KQ2FwMDEwXzIgPUNhcDAxMF8yWyxjKDEsNyldDQoNCkNhcDAxMF8yJERFUEFSVEFNRU5UTyA9Z3N1YignIFswLTldLicsICcnLCBDYXAwMTBfMiRERVBBUlRBTUVOVE8pDQpgYGANCg0KIyMgMi4xLjENCmBgYHtyfQ0KdXJsIDwtICJodHRwczovL2dpdGh1Yi5jb20vQ2hpYXJhWmFtb3JhTS9PRFMvcmF3L21haW4vMi4yLjEueGxzeCINCmRlc3RmaWxlIDwtICJYMl8yXzEueGxzeCINCmN1cmw6OmN1cmxfZG93bmxvYWQodXJsLCBkZXN0ZmlsZSkNClgyXzJfMSA8LSByZWFkX2V4Y2VsKGRlc3RmaWxlLCBza2lwID0gNykNCm5hbWVzKFgyXzJfMSlbMV09ICJERVBBUlRBTUVOVE8iDQoNCkNhcDAxMCRERVBBUlRBTUVOVE89IGdzdWIoIlByb3YuIENvbnN0LiBkZWwgQ2FsbGFvIiwiQ2FsbGFvIixDYXAwMTAkREVQQVJUQU1FTlRPKQ0KQ2FwMDEwJERFUEFSVEFNRU5UTz0gZ3N1YigiTGltYSBNZXRyb3BvbGl0YW5hIiwiTElNQSIsQ2FwMDEwJERFUEFSVEFNRU5UTykNCkNhcDAxMCRERVBBUlRBTUVOVE89IGdzdWIoIkRlcGFydGFtZW50byBkZSBMaW1hIiwiTElNQSBQUk9WSU5DSUFTIixDYXAwMTAkREVQQVJUQU1FTlRPKQ0KDQpYMl8yXzEkREVQQVJUQU1FTlRPPSBnc3ViKCJQcm92LiBDb25zdC4gZGVsIENhbGxhbyIsIkNhbGxhbyIsWDJfMl8xJERFUEFSVEFNRU5UTykNClgyXzJfMSRERVBBUlRBTUVOVE89IGdzdWIoIlByb3ZpbmNpYSBkZSBMaW1hIiwiTElNQSIsWDJfMl8xJERFUEFSVEFNRU5UTykNClgyXzJfMSRERVBBUlRBTUVOVE89IGdzdWIoIlJlZ2nDs24gTGltYSIsIkxJTUEgUFJPVklOQ0lBUyIsWDJfMl8xJERFUEFSVEFNRU5UTykNCg0KWDJfMl8xID0gbWVyZ2UoWDJfMl8xLCBDYXAwMTAsIGJ5ID0gIkRFUEFSVEFNRU5UTyIpDQoNCm5hbWVzKFgyXzJfMSlbYygyOjE1KV0gPSBwYXN0ZTAoIk9EUzJfMl8xXyIsbmFtZXMoWDJfMl8xKVtjKDI6MTUpXSkNCmBgYA0KDQojIyAyLjIuMQ0KYGBge3J9DQp1cmwgPC0gImh0dHBzOi8vZ2l0aHViLmNvbS9DaGlhcmFaYW1vcmFNL09EUy9yYXcvbWFpbi8yLjIuMi54bHN4Ig0KZGVzdGZpbGUgPC0gIlgyXzJfMi54bHN4Ig0KY3VybDo6Y3VybF9kb3dubG9hZCh1cmwsIGRlc3RmaWxlKQ0KWDJfMl8yIDwtIHJlYWRfZXhjZWwoZGVzdGZpbGUsIHNraXAgPSA3KQ0KbmFtZXMoWDJfMl8yKVsxXT0gIkRFUEFSVEFNRU5UTyINCmBgYA0KDQpgYGB7cn0NCkNhcDAxMF8yJERFUEFSVEFNRU5UTz0gZ3N1YigiUHJvdi4gQ29uc3QuIGRlbCBDYWxsYW8iLCJDYWxsYW8iLENhcDAxMF8yJERFUEFSVEFNRU5UTykNCkNhcDAxMF8yJERFUEFSVEFNRU5UTz0gZ3N1YigiTGltYSBNZXRyb3BvbGl0YW5hIiwiTElNQSIsQ2FwMDEwXzIkREVQQVJUQU1FTlRPKQ0KQ2FwMDEwXzIkREVQQVJUQU1FTlRPPSBnc3ViKCJEZXBhcnRhbWVudG8gZGUgTGltYSIsIkxJTUEgUFJPVklOQ0lBUyIsQ2FwMDEwXzIkREVQQVJUQU1FTlRPKQ0KDQpYMl8yXzIkREVQQVJUQU1FTlRPPSBnc3ViKCJQcm92LiBDb25zdC4gZGVsIENhbGxhbyIsIkNhbGxhbyIsWDJfMl8yJERFUEFSVEFNRU5UTykNClgyXzJfMiRERVBBUlRBTUVOVE89IGdzdWIoIlByb3ZpbmNpYSBkZSBMaW1hIiwiTElNQSIsWDJfMl8yJERFUEFSVEFNRU5UTykNClgyXzJfMiRERVBBUlRBTUVOVE89IGdzdWIoIlJlZ2nDs24gTGltYSIsIkxJTUEgUFJPVklOQ0lBUyIsWDJfMl8yJERFUEFSVEFNRU5UTykNCmBgYA0KDQpgYGB7cn0NClgyXzJfMiA9IG1lcmdlKFgyXzJfMiwgQ2FwMDEwXzIsIGJ5ID0gIkRFUEFSVEFNRU5UTyIpDQoNCmNvbG5hbWVzKFgyXzJfMilbYygyOjEyKV0gPSBwYXN0ZTAoIk9EUzJfMl8yXyIsY29sbmFtZXMoWDJfMl8yKVtjKDI6MTIpXSkNCg0Kc3RyKFgyXzJfMikNCmBgYA0KDQojIyBNZXJnZQ0KYGBge3J9DQpPRFNfMiA9IFJlZHVjZShmdW5jdGlvbih4LCB5KSBtZXJnZSh4LCB5LCBieT0gIkRFUEFSVEFNRU5UTyIpLCBsaXN0KFgyXzJfMSxYMl8yXzIpKQ0KYGBgDQoNCmBgYHtyfQ0KT0RTXzJbLGMoMjoyNildPWxhcHBseShPRFNfMlssYygyOjI2KV0sIGFzLm51bWVyaWMpDQpgYGANCg0KIyBNZXJnZQ0KYGBge3J9DQpPRFMgPSBSZWR1Y2UoZnVuY3Rpb24oeCwgeSkgbWVyZ2UoeCwgeSwgYnk9ICJERVBBUlRBTUVOVE8iKSwgbGlzdChPRFNfMSxPRFNfMikpDQoNCmxpYnJhcnkoc3RyaW5naSkNCk9EUyRERVBBUlRBTUVOVE89IHN0cmlfdHJhbnNfZ2VuZXJhbChzdHIgPSB0b3VwcGVyKE9EUyRERVBBUlRBTUVOVE8pLCBpZCA9ICJMYXRpbi1BU0NJSSIpDQoNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KHN0cmluZ2kpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KDQpPRFNUcmFucz0gT0RTICU+JSBnYXRoZXIoIE9EU19Bbm8sIFZhbG9yLCAyOjYyLCBuYS5ybSA9IFRSVUUsIGNvbnZlcnQgPSBGQUxTRSkNCg0KT0RTVHJhbnMkQW5vPSBzdWIoJy4qKFxcZHs0fSkuKicsICdcXDEnLCBPRFNUcmFucyRPRFNfQW5vKQ0KT0RTVHJhbnMkQW5vID0gYXMuRGF0ZShhcy5jaGFyYWN0ZXIoT0RTVHJhbnMkQW5vKSwgZm9ybWF0ID0gIiVZIikNCk9EU1RyYW5zJEFubzwtIHllYXIoT0RTVHJhbnMkQW5vKQ0KT0RTVHJhbnMkT0RTTnJvPSBzdHJfZXh0cmFjdChPRFNUcmFucyRPRFNfQW5vLCdbMC05XVxcX1swLTldXFxfWzAtOV0nKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShzZikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dwdWJyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdncmVwZWwpDQpsaWJyYXJ5KHJlcHIpDQpsaWJyYXJ5KGR5Z3JhcGhzKQ0KbGlicmFyeShxdWFudG1vZCkNCmxpYnJhcnkocmpzb24pDQoNCmRvd25sb2FkLmZpbGUoImh0dHBzOi8vZ2l0aHViLmNvbS9DaGlhcmFaYW1vcmFNL09EUy9yYXcvbWFpbi9tYXBhX1BlcnUvbWFwYV9kZXBhc19MaW1hLnppcCIsIA0KICAgICAgICAgICAgICBkZXN0ZmlsZSA9ICJtYXBhX2RlcGFzX0xpbWEuemlwIiAsIG1vZGU9J3diJykNCnVuemlwKCJtYXBhX2RlcGFzX0xpbWEuemlwIiwgZXhkaXIgPSAiLiIpDQpmaWxlLnJlbW92ZSgibWFwYV9kZXBhc19MaW1hLnppcCIpDQoNCm1hcGEgPC0gc3RfcmVhZCgibWFwYV9kZXBhc19MaW1hLnNocCIpDQoNCmRvd25sb2FkLmZpbGUoImh0dHBzOi8vZ2l0aHViLmNvbS9DaGlhcmFaYW1vcmFNL09EUy9yYXcvbWFpbi9tYXBhMl9QZXJ1L1Byb3ZpbmNpYXNfUGVydS56aXAiLCANCiAgICAgICAgICAgICAgZGVzdGZpbGUgPSAiUHJvdmluY2lhc19QZXJ1LnppcCIgLCBtb2RlPSd3YicpDQp1bnppcCgiUHJvdmluY2lhc19QZXJ1LnppcCIsIGV4ZGlyID0gIi4iKQ0KZmlsZS5yZW1vdmUoIlByb3ZpbmNpYXNfUGVydS56aXAiKQ0KbWFwYV9wcm92IDwtIHN0X3JlYWQoIlBST1ZJTkNJQVMuc2hwIikNCg0KbWFwYV9wcm92JERFUEFSVEFNRU4gPC0gaWZlbHNlKG1hcGFfcHJvdiRQUk9WSU5DSUEgPT0gIkxJTUEiLCAiTElNQSBNRVRST1BPTElUQU5BIiwgbWFwYV9wcm92JERFUEFSVEFNRU4pDQoNCm1hcGFfcHJvdj0gZm9ydGlmeShtYXBhX3Byb3YpDQpgYGANCg0KYGBge3J9DQptYXBhT0RTID0gbWVyZ2UobWFwYSwgT0RTVHJhbnMsDQogICAgICAgICAgICAgIGJ5Lng9J0RFUEFSVEFNRU4nLGJ5Lnk9IkRFUEFSVEFNRU5UTyIpDQoNCiNtYXBhT0RTIDwtIG1hcGFPRFMgJT4lIG11dGF0ZShjZW50cm9pZCA9IG1hcChnZW9tZXRyeSwgc3RfY2VudHJvaWQpLCANCiAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHMgPSBtYXAoY2VudHJvaWQsIHN0X2Nvb3JkaW5hdGVzKSwgDQogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRzX3ggPSBtYXBfZGJsKGNvb3JkcywgMSksIA0KICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc195ID0gbWFwX2RibChjb29yZHMsIDIpKQ0KDQpzdWJzZXQxXzFfMT0gc3Vic2V0KG1hcGFPRFMsIE9EU05ybz09IjFfMV8xIiAmIEFubz4gMjAxNCkNCg0KYmFzZTFfMV8xPSBnZ3Bsb3QoZGF0YSA9IHN1YnNldDFfMV8xKSArIHRoZW1lX2xpZ2h0KCkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KDQptYXBhbGV5MSA9IGJhc2UxXzFfMSArDQogIGdlb21fc2YoYWVzKGZpbGw9IFZhbG9yKSkgKyBsYWJzKGZpbGwgPSAiUG9yY2VudGFqZSAoJSkiKSArDQogIGdlb21fc2YoZGF0YSA9IG1hcGFfcHJvdiwNCiAgICAgICAgICBmaWxsID0gTkEpICsNCiAgZmFjZXRfd3JhcCh+QW5vKQ0KICAgICAgDQptYXBhMSA9IG1hcGFsZXkxICsgDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImxpZ2h0cGluayIsICBoaWdoID0gImZpcmVicmljazIiKSsgDQogIGxhYnModGl0bGUgPSAiSW5jaWRlbmNpYSBkZSBsYSBwb2JyZXphIGV4dHJlbWEiLCBzdWJ0aXRsZSA9ICJJbmRpY2Fkb3IgMS4xLjEiKSANCg0KbWFwYTENCmBgYA0KDQpgYGB7cn0NCnN1YnNldDFfMl8xPSBzdWJzZXQobWFwYU9EUywgT0RTTnJvPT0iMV8yXzEiICYgQW5vPiAyMDE0KQ0KDQpiYXNlMV8yXzE9IGdncGxvdChkYXRhID0gc3Vic2V0MV8yXzEpICsgdGhlbWVfbGlnaHQoKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQoNCm1hcGFsZXkyID0gYmFzZTFfMl8xICsNCiAgZ2VvbV9zZihhZXMoZmlsbD0gVmFsb3IpKSArIGxhYnMoZmlsbCA9ICJQb3JjZW50YWplICglKSIpICsNCiAgZ2VvbV9zZihkYXRhID0gbWFwYV9wcm92LA0KICAgICAgICAgIGZpbGwgPSBOQSkgKw0KICBmYWNldF93cmFwKH5Bbm8pDQogICAgICANCm1hcGEyID0gbWFwYWxleTIgKyANCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAibGlnaHRwaW5rIiwgIGhpZ2ggPSAiZmlyZWJyaWNrMiIpKyANCiAgbGFicyh0aXRsZSA9ICJJbmNpZGVuY2lhIGRlIGxhIHBvYnJlemEgbW9uZXRhcmlhIHRvdGFsIiwgc3VidGl0bGUgPSAiSW5kaWNhZG9yIDEuMi4xIikgDQoNCm1hcGEyDQpgYGANCg0KYGBge3J9DQpzdWJzZXQxXzNfMT0gc3Vic2V0KG1hcGFPRFMsIE9EU05ybz09IjFfM18xIiAmIEFubz4gMjAxNCkNCg0KYmFzZTFfM18xPSBnZ3Bsb3QoZGF0YSA9IHN1YnNldDFfM18xKSArIHRoZW1lX2xpZ2h0KCkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KDQptYXBhbGV5MyA9IGJhc2UxXzNfMSArDQogIGdlb21fc2YoYWVzKGZpbGw9IFZhbG9yKSkgKyBsYWJzKGZpbGwgPSAiUG9yY2VudGFqZSAoJSkiKSArDQogIGdlb21fc2YoZGF0YSA9IG1hcGFfcHJvdiwNCiAgICAgICAgICBmaWxsID0gTkEpICsNCiAgZmFjZXRfd3JhcCh+QW5vKQ0KICAgICAgDQptYXBhMyA9IG1hcGFsZXkzICsgDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImxpZ2h0cGluayIsICBoaWdoID0gImZpcmVicmljazIiKSsgDQogIGxhYnModGl0bGUgPSAiUHJvcG9yY2nDs24gZGUgcG9ibGFjacOzbiBkZSAxNCBhIG3DoXMgYcOxb3MgZGUgZWRhZCBcbmNvbiBzZWd1cm8gZGUgcGVuc2nDs24iLCBzdWJ0aXRsZSA9ICJJbmRpY2Fkb3IgMS4zLjEiKSANCg0KbWFwYTMNCmBgYA0KDQpgYGB7cn0NCnN1YnNldDFfNF8xPSBzdWJzZXQobWFwYU9EUywgT0RTTnJvPT0iMV80XzEiICYgQW5vPiAyMDE0KQ0KDQpiYXNlMV80XzE9IGdncGxvdChkYXRhID0gc3Vic2V0MV80XzEpICsgdGhlbWVfbGlnaHQoKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQoNCm1hcGFsZXk0ID0gYmFzZTFfNF8xICsNCiAgZ2VvbV9zZihhZXMoZmlsbD0gVmFsb3IpKSArIGxhYnMoZmlsbCA9ICJQb3JjZW50YWplICglKSIpICsNCiAgZ2VvbV9zZihkYXRhID0gbWFwYV9wcm92LA0KICAgICAgICAgIGZpbGwgPSBOQSkgKw0KICBmYWNldF93cmFwKH5Bbm8pDQogICAgICANCm1hcGE0ID0gbWFwYWxleTQgKyANCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAibGlnaHRwaW5rIiwgIGhpZ2ggPSAiZmlyZWJyaWNrMiIpKyANCiAgbGFicyh0aXRsZSA9ICJQcm9wb3JjacOzbiBkZSBsYSBwb2JsYWNpw7NuIHF1ZSB2aXZlIGVuIGhvZ2FyZXMgY29uIFxuYWNjZXNvIGEgc2VydmljaW9zIGLDoXNpY29zIGRlIGluZnJhZXN0cnVjdHVyYSIsIHN1YnRpdGxlID0gIkluZGljYWRvciAxLjQuMSIpIA0KDQptYXBhNA0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShsZWFmbGV0KQ0KYGBgDQoNCmBgYHtyfQ0KcGFsMSA9IGNvbG9yTnVtZXJpYyhwYWxldHRlID0gIkJsdWVzIiwgZG9tYWluID0gc3Vic2V0MV8xXzEkVmFsb3IpDQpgYGANCg0KYGBge3J9DQpuYW1lcyhzdWJzZXQxXzFfMSkNCmBgYA0KDQoNCmBgYHtyfQ0KbWFwMV9pbnRlcmFjdGl2ZSA9IHN1YnNldDFfMV8xICAlPiUgDQogIHN0X3RyYW5zZm9ybShjcnM9ICIraW5pdD1lcHNnOjQzMjYiKSAlPiUNCiAgbGVhZmxldCgpICU+JQ0KICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVyPSAiQ2FydG9EQi5Qb3NpdHJvbiIpICU+JQ0KICBhZGRQb2x5Z29ucyhsYWJlbD0gc3Vic2V0MV8xXzEkREVQQVJUQU1FTiwNCiAgICAgICAgICAgICAgc3Ryb2tlID0gRkFMU0UsIA0KICAgICAgICAgICAgICBzbW9vdGhGYWN0b3IgPSAgLjUsDQogICAgICAgICAgICAgIG9wYWNpdHkgPSAxLA0KICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNywNCiAgICAgICAgICAgICAgZmlsbENvbG9yID0gfnBhbDEoVmFsb3IpLA0KICAgICAgICAgICAgICBoaWdobGlnaHRPcHRpb25zID0gaGlnaGxpZ2h0T3B0aW9ucyh3ZWlnaHQgPSA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eT0gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5ID0gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJpbmdUb0Zyb250ID0gVFJVRSkpJT4lDQoNCiAgYWRkTGVnZW5kKCJib3R0b21yaWdodCIsDQogICAgICAgICAgICBwYWwgPSBwYWwxLA0KICAgICAgICAgICAgdmFsdWVzID0gflZhbG9yLA0KICAgICAgICAgICAgdGl0bGU9ICJQb3JjZW50YWplICglKSIsDQogICAgICAgICAgICBvcGFjaXR5PSAwLjcpIA0KDQptYXAxX2ludGVyYWN0aXZlDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGh0bWx3aWRnZXRzKQ0Kc2F2ZVdpZGdldChtYXAxX2ludGVyYWN0aXZlLCAiT0RTMV8xXzEuaHRtbCIpDQpgYGANCiAgDQpgYGB7cn0NCnNhdmVSRFMoc3Vic2V0MV8xXzEsICJzdWJzZXRfMV8xXzEuUkRTIikNCmBgYA0KDQo=